import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.DriverManagerDataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.jndi.JndiObjectFactoryBean;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.sql.SQLException;

import static org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType.H2;

public class Config {

    @Bean
    public DataSource DataSource(){
        BasicDataSource source=new BasicDataSource();
        /*
        必须的配置
         */
        source.setDriverClassName("com.mysql.jdbc.Driver");//设置驱动器
        source.setUrl("jdbc:mysql://127.0.0.1:3306/long1?characterEncoding=UTF8");//设置连接地址
        source.setUsername("username");//设置用户名
        source.setPassword("password");//设置密码
        /*
        可选的配置
         */
        source.setInitialSize(10);//设置初始化后的连接数
        source.setMaxActive(10);//设置最大的连接数
        source.setDefaultAutoCommit(true);//设置连接是否默认自动提交
        source.setMaxIdle(100);//设置最长的等待时间,超出则断开连接
        source.setMinIdle(20);//设置最短的等待时间
        source.setMaxWait(30);//设置最大的等待时间,如果超过此时间将接到异常。设为-1表示无限制
        source.setMaxOpenPreparedStatements(40);//设置连接池开启proped后的同一时刻最大连接数(默认无上限)
        return source;
    }

    @Bean
    public ComboPooledDataSource comboPooledDataSource() throws PropertyVetoException {
        ComboPooledDataSource source=new ComboPooledDataSource();//创建c3p0连接池数据源对象
        source.setDriverClass("com.mysql.jdbc.Driver");//设置驱动器
        source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/long1?characterEncoding=UTF8");//设置连接地址
        source.setUser("username");//用户名
        source.setPassword("password");//密码
        source.setAcquireIncrement(3);//连接耗尽一次性同时获取的连接数
        source.setInitialPoolSize(8);//初始化后的连接数
        source.setMinPoolSize(5);//池中保留的最小连接数
        source.setMaxPoolSize(10);//保留的最大连接数
        source.setMaxIdleTime(60);//最长空闲时间
        source.setIdleConnectionTestPeriod(60);//间隔时间检查空闲的连接数
        source.setMaxStatements(10);//连接池中preparedStatements的最大数量
        source.setMaxStatementsPerConnection(0);//与缓存有关
        source.setNumHelperThreads(3);//与性能有关
        return source;
    }

    @Bean
    public DruidDataSource druidDataSource() throws SQLException {
        DruidDataSource source = new DruidDataSource();//创建druid数据源对象
        source.setName("username");//用户名
        source.setPassword("password");//密码
        source.setUrl("jdbc:mysql://127.0.0.1:3306/long1?characterEncoding=UTF8");//连接地址
        source.setFilters("stat");//配置监控统计拦截的filters
        source.setMaxActive(20);//最大连接数
        source.setInitialSize(1);//初始化后的连接数
        source.setMaxWait(60000);//连接等待超时时间
        source.setMinIdle(1);//连接池不会被释放的最多空闲连接数
        source.setTimeBetweenEvictionRunsMillis(60000);//多久检测一次可以关闭的空闲连接
        /*建议配置为true，不影响性能，并且保证安全性。申请连接的时候检测，
        如果空闲时间大于timeBetweenEvictionRunsMillis，执行validationQuery检测连接是否有效
        */
        source.setTestWhileIdle(true);
        //申请连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能
        source.setTestOnBorrow(false);
        //归还连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能
        source.setTestOnReturn(false);
        //是否启动缓存preparedStatement
        source.setPoolPreparedStatements(true);
        //在同一时间能够从语句池中分配的预处理语句的最大数量
        source.setMaxOpenPreparedStatements(20);
        //设置异步初始化
        source.setAsyncInit(true);
        //连接在连接池中空闲不被回收的最长时间
        source.setMinEvictableIdleTimeMillis(30000);
        return source;
    }
    /*
    基于jdbc的DriverManagerDataSource数据源
     */
    @Bean
    public DriverManagerDataSource driverManagerDataSource(){
        DriverManagerDataSource source=new DriverManagerDataSource();
        source.setDriverClass("com.mysql.jdbc.driver");
        source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306");
        source.setUser("username");
        source.setPassword("password");
        return source;
    }

    /*
    基于jsbc的SimpleDriverDataSource数据源
     */
    @Bean
    public SimpleDriverDataSource simpleDriverDataSource(){
        SimpleDriverDataSource source=new SimpleDriverDataSource();//创建简单的驱动数据源
        source.setDriver(new Drivers());//设置驱动类(创建实现Driver驱动接口的类)
        source.setUrl("jdbc:mysql://127.0.0.1:3306");
        source.setUsername("username");
        source.setPassword("password");
        return source;
    }

    /*
    基于SingleConnectionDataSourcejdbc的数据源
     */

    @Bean
    public SingleConnectionDataSource singleConnectionDataSource(){
        SingleConnectionDataSource source=new SingleConnectionDataSource();
        source.setDriverClassName("com.mysql.jdbc.Driver");
        source.setUrl("jdbc:mysql://127.0.0.1:3306");
        source.setUsername("username");
        source.setPassword("password");
        return source;
    }

    /*
    嵌入式数据源
     */

    @Bean
    public DataSource dataSource(){
        return new EmbeddedDatabaseBuilder().setType(H2).addScript(".sql文件地址").addScript(".sql文件地址").build();
    }

    @Bean
    public DataSource dataSource2(){
        EmbeddedDatabaseBuilder builder=new EmbeddedDatabaseBuilder();//构建基本嵌入数据
        builder.setType(H2);//设置数据库种类
        builder.addScript(".sql文件地址");//设置sql文件地址
        builder.addScript(".sql文件地址");
        return builder.build();//构建数据源
    }

    /*
    使用@profile注解选择数据源
     */

    @Bean
    @Profile("QA")//设置QA第三方评测数据源
    public DataSource basicDataSource(){
        BasicDataSource source=new BasicDataSource();
        source.setDriverClassName("com.mysql.jdbc.Driver");
        source.setUrl("jdbc:mysql://127.0.0.1:3306");
        source.setUsername("username");
        source.setPassword("password");
        return source;
    }

    @Bean
    @Profile("Embedded")//设置开发环境数据源
    public DataSource EmbeddedDataSource(){
        EmbeddedDatabaseBuilder builder=new EmbeddedDatabaseBuilder();
        builder.setType(H2);
        builder.addScript("/sql文件地址");
        return builder.build();
    }

    @Bean
    @Profile("jndi")//设置生产环境数据源
    public DataSource jndiDataSource(){
        JndiObjectFactoryBean bean=new JndiObjectFactoryBean();
        bean.setJndiName("jndiName");
        bean.setResourceRef(true);
        bean.setProxyInterface(javax.sql.DataSource.class);
        return (DataSource) bean.getObject();
    }











}
